#include <iostream>
using namespace std;

const int maxN = 101;
int g[maxN][maxN]; // cost array.
int N;  // vertex numbers.
int flag[maxN]; // indicate whether a vertex is visited. 0 is false, 1 is true.
int dist[maxN]; // store distance.
int path[maxN]; // vertex's adjent vertex.

int Prime()
{
	memset(flag, 0, sizeof(flag));
	memset(dist, 1 << 30, sizeof(dist));
	memset(path, 0, sizeof(path));

	int sum = 0;

	flag[1] = 1; // all index starts from 1.
	path[1] = 0;
	for (int i = 2; i <= N; i++) {
		dist[i] = g[1][i];
		path[i] = 1;
	}
	for (int i = 2; i <= N; i++) {
		int k;
		int minvalue = 1 << 30;
		
		for (int j = 2; j <= N; j++) 
			if (flag[j] == 0 && dist[j] < minvalue) {
				minvalue = dist[j];	
				k = j;
			}	
		flag[k] = 1;
		sum += minvalue;
		for (int m = 2; m <= N; m++) {
			if (m != k && flag[m] == 0 && dist[m] > g[m][k]) {
				dist[m] = g[m][k];
				path[m] = k;
			}
		}
	}

	return sum;
}

int main()
{
	while (cin >> N) {
		memset(g, 1 << 30, sizeof(g));
		for (int i = 1; i <= N; i++) 
			for (int j = 1; j <= N; j++) 
				cin >> g[i][j];	
		int numofav;
		cin >> numofav;
		for (int i = 1; i <= numofav; i++) {
			int k, j;
			cin >> k >> j;
			g[k][j] = g[j][k] = 0;
		}
	    cout <<	Prime() << endl;
	}
	return 0;
}

